# coding:utf-8

from sqlalchemy import Column, Integer, Numeric, String, TIMESTAMP
from sqlalchemy.dialects.postgresql import JSON
import json, uuid, sql


class Area(sql.db.Model):
    __tablename__ = 'area'
    """
        地区信息，包含了地区的polygon坐标数据以及边界、中心点坐标
    """

    internal_name = Column(String, unique=True)
    """
        地区级别，从0递增分别表示 国家、省、市、地区
    """
    level = Column(Integer)

    """
        GeoJSON的geometry类型
    """
    geom_type = Column(String)

    """
        Polygon或者MultiPolygon的坐标信息
    """
    coordinates = Column(JSON)

    """
        边界和中心坐标，在首次提交到数据库中时计算得出并更新，后续可以强制更新
    """
    key = Column(Numeric)
    left = Column(Numeric)
    top = Column(Numeric)
    right = Column(Numeric)
    bottom = Column(Numeric)
    center_x = Column(Numeric)
    center_y = Column(Numeric)

    uuid = Column(String, primary_key=True)

    parent = Column(String)

    """
        国际化名称
    """
    i18n = Column(JSON)

    # gmt_created = Column(TIMESTAMP)
    # gmt_modified = Column(TIMESTAMP)

    def __set_bound__(self, point):
        if point[0] < self.left:
            self.left = point[0]
        if point[0] > self.right:
            self.right = point[0]

        if point[1] < self.bottom:
            self.bottom = point[1]
        if point[1] > self.top:
            self.top = point[1]

    """
        返回当前地区的边界坐标，按照top,right,bottom,left,centerX,centerY的顺序组成tuple
        forceUpdate = True时将根据当前的coordinates重新计算坐标
    """

    def bound(self, force_update=False):
        if force_update:

            self.top = None
            self.right = None
            self.left = float('inf')
            self.bottom = float('inf')

            if self.geom_type == 'polygon':
                for p in self.coordinates[0]:
                    self.__set_bound__(p)
            elif self.geom_type == 'multipolygon':
                for polygon in self.coordinates:
                    for p in polygon[0]:
                        self.__set_bound__(p)
            else:
                raise TypeError("不支持的类型%s" % self.geom_type)

            self.center_x = (self.left + self.right) / 2
            self.center_y = (self.top + self.bottom) / 2

        return self.top, self.right, self.bottom, self.left, self.center_x, self.center_y

    def __init__(self, geo):

        self.internal_name = geo["properties"]["name"]
        self.geom_type = geo["geometry"]["type"].lower()
        self.coordinates = geo["geometry"]["coordinates"]
        self.level = geo["properties"]["level"]
        self.key = 3
        self.parent = geo["properties"]["parent"]
        self.uuid = uuid.uuid4()
        self.bound(True)

    def i18n(self, lang, default=None):
        try:
            return self.i18n[lang]
        except:
            return default if default is not None else ''


def delete_polygon(uuid, filter):
    area = Area.query.filter_by(uuid=uuid).first()
    coord_n = []
    i = -1
    for polygon in area.coordinates:
        i += 1
        if filter(polygon):
            print "第%d个Polygon可以删除" % i
            continue
        coord_n.append(polygon)
    area.coordinates = coord_n
    sql.db.session.commit()


def update_bound():
    area = Area.query.filter_by(uuid='e6320f64-8fa6-46c1-8e4c-185f86f762dc').first()
    geo = dict()
    geo["geometry"] = dict()
    geo["properties"] = dict()
    geo["geometry"]["coordinates"] = area.coordinates
    geo["properties"]["name"] = None
    geo["geometry"]["type"] = 'multipolygon'
    geo["properties"]["level"] = area.level
    geo["properties"]["key"] = area.key
    geo["properties"]["parent"] = area.parent

    na = Area(geo)
    pos = na.bound()
    area.top = pos[0]
    area.right = pos[1]
    area.bottom = pos[2]
    area.left = pos[3]
    area.center_x = pos[4]
    area.center_y = pos[5]
    sql.db.session.commit()


def add_province(folder):
    import os

    for f in os.listdir(folder):
        if f.endswith(".json"):
            f = "%s%s%s" % (folder, os.sep, f)
            province = json.load(open(f))
            print province
            for city in province["features"]:
                city["properties"]["level"] = 2
                city["properties"]["parent"] = province["uuid"]
                area = Area(city)
                print area.coordinates
                sql.db.session.add(area)
            print("%s is load" % f)
    sql.db.session.commit()

def add_city(f):
    jf = open(f)
    city = json.load(jf)
    print city
    for town in city["features"]:
        town["properties"]["level"] = 3
        town["properties"]["parent"] ="22"
        #town["geometry"]["coordinates"]=towm['geometry']['coordinates']
        area = Area(town)
        sql.db.session.add(area)
   # print("%s is load" % f)
    sql.db.session.commit()


if __name__ == '__main__':
    '''
    world = json.load(open('./res/us.geojson'))
    for nation in world["features"]:
        nation["properties"]["level"] = 1
        nation["properties"]["parent"] = '34cf9d25-22e9-4002-b16c-5ee78a6e1ca3'
        area = Area(nation)
        sql.db.session.add(area)
    sql.db.session.commit()
    '''

    '''
    def gt(polygon):
        coord = polygon[0][0]
        return coord[0] > 133

    delete_polygon('e6320f64-8fa6-46c1-8e4c-185f86f762dc', gt)
    '''
    #add_province("res/china")
    #add_city("/Users/hoyt/git/zhixing/heatmap/res/china/zhejiang/hangzhou.json")
